package cn.melonlib.reports.comp.service;

import cn.hutool.core.lang.UUID;
import cn.melonlib.cores.jpa.model.bean.collections.JsonMap;
import cn.melonlib.tools.db.schemas.comp.dao.ModelDescriptionRetrieval;
import cn.melonlib.tools.db.schemas.comp.dao.impl.MysqlDatabaseSchemasDao;
import cn.melonlib.tools.db.schemas.model.views.ModelDescription;
import lombok.Getter;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.export.ooxml.JRDocxExporter;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

@Service
@Getter
public class ModelDescriptionExportService extends ApplicationObjectSupport {

    private final JsonMap<ModelDescriptionRetrieval> retrievalJsonMap= JsonMap.createMap();

    @Resource
    private MysqlDatabaseSchemasDao mysqlDatabaseSchemasDao;

    @PostConstruct
    public void init(){
        retrievalJsonMap.append("mysql",mysqlDatabaseSchemasDao);
    }

    public File exportDataSchemas(String storeType,String schemaName,String title,String reportType,JsonMap<String> params) throws Exception{
        List<ModelDescription> modelDescriptions=this.retrievalJsonMap.get(StringUtils.defaultIfBlank(storeType,"mysql")).getModels(schemaName,params);
        ClassPathResource resource=new ClassPathResource("/database_schemas.jrxml");
        ClassPathResource subresource=new ClassPathResource("/database_tables.jrxml");
        try(InputStream in=resource.getInputStream(); InputStream subIn=subresource.getInputStream()){
            JasperReport jasperReport= JasperCompileManager.compileReport(in);
            JasperReport jasperReportSub= JasperCompileManager.compileReport(subIn);
            JasperPrint print= JasperFillManager.fillReport(jasperReport, JsonMap.createMap()
                            .append("tables",modelDescriptions)
                            .append("columnsPath",jasperReportSub)
                            .append("title",title)
                            .append("showTables",List.of(JsonMap.createMap().append("data",modelDescriptions)))
                    ,new JREmptyDataSource());
            return switch (reportType){
                case "docx"->exportToDocx(print);
                case "html"->exportToHTML(print);
                default -> exportToPdf(print);
            };
        }
    }

    public File exportToDocx(JasperPrint print) throws Exception{
        File file=new File("/service/reports/"+ UUID.fastUUID() +".docx");
        JRDocxExporter exporter=new JRDocxExporter();
        exporter.setExporterInput(new SimpleExporterInput(print));
        exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(file));
        exporter.exportReport();
        return file;
    }

    public File exportToPdf(JasperPrint print) throws Exception{
        File file=new File("/service/reports/"+ UUID.fastUUID() +".pdf");
        byte [] data= JasperExportManager.exportReportToPdf(print);
        FileUtils.writeByteArrayToFile(file,data);
        return file;
    }
    public File exportToHTML(JasperPrint print) throws Exception{
        File file=new File("/service/reports/"+ UUID.fastUUID() +".pdf");
        JasperExportManager.exportReportToHtmlFile(print,file.getAbsolutePath());
        return file;
    }
}
